package com.hc.usb.impl;

import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class USBCommandBase {
    public static final byte IN = (byte) 0x80;
    public static final byte OUT = 0x00;
    public static final int dCBWSignature = 0x43425355;
    int dCBWTag;
    int dCBWDataTransferLength;
    byte bmCBWFlags;
    byte bCBWLUN = 0;

    public USBCommandBase(int dCBWTag, int dCBWDataTransferLength, byte bmCBWFlags) {
        this.dCBWTag = dCBWTag;
        this.dCBWDataTransferLength = dCBWDataTransferLength;
        this.bmCBWFlags = bmCBWFlags;
    }

    public void serialize(ByteBuffer buffer){
        buffer.order(ByteOrder.LITTLE_ENDIAN)
                .putInt(dCBWSignature)
                .putInt(dCBWTag)
                .putInt(dCBWDataTransferLength)
                .put(bmCBWFlags)
                .put(bCBWLUN);
    }

    public void command(UsbDeviceConnection usbDeviceConnection, UsbEndpoint usbEndpoint){
        ByteBuffer buffer = ByteBuffer.allocate(31);
        buffer.clear();
        serialize(buffer);
        usbDeviceConnection.bulkTransfer(usbEndpoint,buffer.array(),0,31,5000);
    }

    public ByteBuffer data(UsbDeviceConnection usbDeviceConnection,UsbEndpoint usbEndpoint){
        ByteBuffer buffer = ByteBuffer.allocate(dCBWDataTransferLength);
        buffer.clear();
        usbDeviceConnection.bulkTransfer(usbEndpoint,buffer.array(),0,dCBWDataTransferLength,5000);
        return buffer;
    }

    public void status(UsbDeviceConnection usbDeviceConnection,UsbEndpoint usbEndpoint){
        ByteBuffer buffer = ByteBuffer.allocate(13).order(ByteOrder.LITTLE_ENDIAN);
        buffer.clear();
        usbDeviceConnection.bulkTransfer(usbEndpoint,buffer.array(),0,13,5000);
        int dCSWSignature = buffer.getInt();
        int dCSWTag = buffer.getInt();
        int dCSWDataResidue = buffer.getInt();
        byte bCSWStatus = buffer.get();
        Log.d("USBINFO","CommandBase dCSWSignature:"+dCSWSignature+" dCSWTag:"+dCSWTag+" dCSWDataResidue:"+dCSWDataResidue+" bCSWStatus:"+bCSWStatus);
    }

    public ByteBuffer execute(UsbDeviceConnection usbDeviceConnection,UsbEndpoint in,UsbEndpoint out){
        command(usbDeviceConnection,out);
        ByteBuffer data = data(usbDeviceConnection, in);
        status(usbDeviceConnection,in);
        return data;
    }
}
